﻿using Nemerle.Data;
//using Nemerle.Data.Arrays;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;

module Program
{ 
  Main() : void
  {
    def garbage = ["ToString", "Equals", "GetHashCode", "GetType"];
    def api = IO.File.ReadAllLines(@"..\..\api.txt");
    //def header = "|| *Method* || *Seq* || *Lists* || *Arrays* || *Strings* ||";
    def modules : list[Type*string] = [(typeof(Seq), ""), (typeof(Seq), "Seq"), (typeof(Arrays), ""), (typeof(NList.NLists),""), (typeof(NList.NLists),"Rev")];
    def header = modules.AsSeq().Fold("|| *Method* ||", (s, (m, postfix)) => s + $" *$(m.Name)$postfix* ||");
    WriteLine(header);
    def mms = modules.ToDictionary(((m,postfix)) => m.Name + postfix, 
      ((m, _)) => m.GetMethods()
          .Map(_.Name)
          //.Map(x => if (x.Contains("Seq")) x.Substring(0, x.Length - 3) else x)
          .Essence()
          .ToDictionary(x => x, _ => string.Empty)
      );
    def report = api.Map(name => modules.Fold($"|| `$name` ||", (s, (m, postfix)) => if (mms[m.Name + postfix].ContainsKey(name + postfix)) s + " *+* ||" else s + " ||"));
    //def rep2 = mms.SelectMany(m => string.Format("*{0}*", m.Key) :: m.Value.Keys.Except(api).ToNList());
    mms
      .Select(m => (string.Format("report_{0}.txt", m.Key), m.Value.Keys.Except(api).Except(garbage)))
      .Iter(((key, values)) => IO.File.WriteAllLines(key, values.ToArray()));
        
    IO.File.WriteAllLines("report_tab.txt", Seq.Single(header).Concat(report).ToArray());
    //IO.File.WriteAllLines("report_2.txt", rep2.ToArray());
    def ms = typeof(Arrays).GetMethods().Filter(m => m.IsPublic && m.IsStatic).Map(_.Name);
    ms.Iter(WriteLine);
    _ = ReadLine();
  }
}